% !TEX TS-program = pdflatex
% !TEX encoding = UTF-8 Unicode

% This is a simple template for a LaTeX document using the "article" class.
% See "book", "report", "letter" for other types of document.

\documentclass[11pt]{article} % use larger type; default would be 10pt

\usepackage[utf8]{inputenc} % set input encoding (not needed with XeLaTeX)
\usepackage{hyperref}

%%% Examples of Article customizations
% These packages are optional, depending whether you want the features they provide.
% See the LaTeX Companion or other references for full information.

%%% PAGE DIMENSIONS
\usepackage{geometry} % to change the page dimensions
\geometry{a4paper} % or letterpaper (US) or a5paper or....
% \geometry{margin=2in} % for example, change the margins to 2 inches all round
% \geometry{landscape} % set up the page for landscape
%   read geometry.pdf for detailed page layout information

\usepackage{graphicx} % support the \includegraphics command and options

% \usepackage[parfill]{parskip} % Activate to begin paragraphs with an empty line rather than an indent

%%% PACKAGES
\usepackage{booktabs} % for much better looking tables
\usepackage{array} % for better arrays (eg matrices) in maths
\usepackage{paralist} % very flexible & customisable lists (eg. enumerate/itemize, etc.)
\usepackage{verbatim} % adds environment for commenting out blocks of text & for better verbatim
\usepackage{subfig} % make it possible to include more than one captioned figure/table in a single float
% These packages are all incorporated in the memoir class to one degree or another...

%%% HEADERS & FOOTERS
\usepackage{fancyhdr} % This should be set AFTER setting up the page geometry
\pagestyle{fancy} % options: empty , plain , fancy
\renewcommand{\headrulewidth}{0pt} % customise the layout...
\lhead{}\chead{}\rhead{}
\lfoot{}\cfoot{\thepage}\rfoot{}

%%% SECTION TITLE APPEARANCE
\usepackage{sectsty}
\allsectionsfont{\sffamily\mdseries\upshape} % (See the fntguide.pdf for font help)
% (This matches ConTeXt defaults)

%%% ToC (table of contents) APPEARANCE
\usepackage[nottoc,notlof,notlot]{tocbibind} % Put the bibliography in the ToC
\usepackage[titles,subfigure]{tocloft} % Alter the style of the Table of Contents
\renewcommand{\cftsecfont}{\rmfamily\mdseries\upshape}
\renewcommand{\cftsecpagefont}{\rmfamily\mdseries\upshape} % No bold!

%%% END Article customizations

%%% The "real" document content comes below...

\title{CS 344 - Final Project}
\author{Michael Depuy}
%\date{} % Activate to display a given date or no date (if empty),
         % otherwise the current date is printed 

\begin{document}
\maketitle
\raggedright
\newpage 

This paper will describe the differences between two different operating system APIs, the first being POSIX and the second being Windows. We will go over four subjects in each API, namely Processes, Threads, Socket Programming, and Message Queues. Each subject will have a brief description of how it works in its named environment (POSIX or Windows), examples of system calls and how they work and differ from the other environment's calls, and possible advantages or disadvantages between the two different versions.

\section{Processes}

Processes (namely creation, execution, and termination) are similar at a high level. However, lower level insight finds many differences between the two.

\subsection{Creating a process}

Creating a process in Windows is done by using the {\em CreateProcess()} command. There are seven steps Windows takes to create a new process:
\begin{enumerate}
\item Convert and validate parameters and flags
\item Open EXE and create section object
\item Create Windows process object
\item Create Windows thread object
\item Perform Windows-specific process initialization, set up for new process and thread
\item Start execution of initial thread, final process/image initialization
\item Return to caller, start execution at entry point to image
\end{enumerate}

\subsubsection{{\em CreateProcess()} Description}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx}{Link to source. [MSDN]}
\begin{verbatim}
BOOL WINAPI CreateProcess(
  _In_opt_     LPCTSTR lpApplicationName,
  _Inout_opt_  LPTSTR lpCommandLine,
  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_         BOOL bInheritHandles,
  _In_         DWORD dwCreationFlags,
  _In_opt_     LPVOID lpEnvironment,
  _In_opt_     LPCTSTR lpCurrentDirectory,
  _In_         LPSTARTUPINFO lpStartupInfo,
  _Out_        LPPROCESS_INFORMATION lpProcessInformation
);
\end{verbatim}

As a key: \textunderscore In\textunderscore\, means that the attribute is input for the function, \textunderscore Out\textunderscore\, is what the function outputs to, and \textunderscore opt\textunderscore\, means the attribute is optional (read: this will be the same for all future Windows defined attributes).

As you can see, there is a stark difference in the information needed to execute a new process. The windows version of {\em CreateProcess()} creates a structure that houses a lot of information about the child process including options such as Security Attributes, the Environment the process will run in, and the child's current directory. The first two arguments are the most important, as they define what kind of executable you will be running. The first argument ({\em lpApplicationName}) specifies what kind of module. If that argument is given an absolute file path, it will execute that module (note: you must include the file extension as nothing is assumed). If left NULL, the function will defer to {\em lpCommandLine}. This argument takes a string of commands that will be executed. This may also be left NULL. However, you cannot have both {\em lpApplicationName} and {\em lpCommandLine} be NULL.

The next two attributes are {\em lpStartupInfo} and {\em lpProcessInformation}. Both of these attributes are structures, {\em LPSTARTUPINFO} and {\em LPPROCESS\textunderscore INFORMATION} respectively. {\em lpStartupInfo} houses all of the data necessary to being execution of the program, mainly details about the environment it is being run in, window type, and standard handles. {\em lpProcessInformation} houses all of the details regarding the process itself, which is the thread ID, process ID, and handles for each. 

Each process gets a home thread. Both the process and its home thread get IDs. Using these IDs is much like using the file descriptor in a POSIX setup. With these handlers, you can perform functions on the processes.

\subsubsection{Return}
This function will return a {\em PROCESS\textunderscore INFORMATION} structure if successful, and zero if unsuccessful. To get error information, use {\em GetLastError()}.

\subsection{Termination}

Much like the POSIX API, a process can continue running even after it finishes executing (normally called a zombie child process). Windows and POSIX have very similar procedures for the successful termination of a process. 
\begin{enumerate}
\item {\em Wait} for a child process, denoted by the {\em Process\textunderscore Information's} handler, to finish executing
\item Call {\em CloseHandle()} on the process handle, then the thread handle.
\end{enumerate}

\subsubsection{{\em WaitForSingleObject()} Description}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx}{Link to source. [MSDN]}
\begin{verbatim}
DWORD WINAPI WaitForSingleObject(
  _In_  HANDLE hHandle,
  _In_  DWORD dwMilliseconds
);
\end{verbatim}

{\em hHandle} refers to the handle the object uses. In our case, this would be the process handle in the {\em Process\textunderscore Information} structure. {\em dwMilliseconds} refers to the amount of time to wait before terminating the process. This may be set to infinity if the process needs a variable amount of time.

\subsubsection{{\em CloseHandle()} Description}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms724211%28v=vs.85%29.aspx}{Link to source. [MSDN]}
\begin{verbatim}
BOOL WINAPI CloseHandle(
  _In_  HANDLE hObject
);
\end{verbatim}

Much like {\em WaitForSingleObject()}, {\em CloseHandle()} uses the handler of the object needing closing. Again, you can get this by referencing the processes' information structure.

\subsubsection{Return}

{\em WaitForSingleObject()} will return a value corresponding to the manner in which the process returned. This could be one of four values:
\begin{itemize}
\item \textbf{WAIT\textunderscore ABANDONED}: The specific object is a mutex object that was not released before the thread owning the object terminated.
\item \textbf{WAIT\textunderscore OBJECT\textunderscore 0}: The object state is signaled (it terminated on its own accord).
\item \textbf{WAIT\textunderscore TIMEOUT}: The object's run time surpassed the time specified by the waiting function and was terminated.
\item \textbf{WAIT\textunderscore FAILED}: Wait function failed.
\end{itemize}

{\em CloseHandle()} will return nonzero if successful and zero if unsuccessful. You may get the error returned by using {\em GetLastError()}.

\subsection{Example Program}
\begin{verbatim}
#include <windows.h>
#include <stdio.h>
#include <tchar.h>

void _tmain( int argc, TCHAR *argv[] )
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;

    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );

    if( argc != 2 )
    {
        printf("Usage: %s [cmdline]\n", argv[0]);
        return;
    }

    // Start the child process. 
    if( !CreateProcess( NULL,   // No module name (use command line)
        argv[1],        // Command line
        NULL,           // Process handle not inheritable
        NULL,           // Thread handle not inheritable
        FALSE,          // Set handle inheritance to FALSE
        0,              // No creation flags
        NULL,           // Use parent's environment block
        NULL,           // Use parent's starting directory 
        &si,            // Pointer to STARTUPINFO structure
        &pi )           // Pointer to PROCESS_INFORMATION structure
    ) 
    {
        printf( "CreateProcess failed (%d).\n", GetLastError() );
        return;
    }

    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess, INFINITE );

    // Close process and thread handles. 
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );
}
\end{verbatim}

\section{Threads}

Threads operate much the same way as processes do in Windows, minus a few of the details when creating a thread versus creating a process. Much like POSIX, threads can perform operations on mutex objects, called on by using the function {\em OpenMutex()} which is fed the mutexes' handle.

\subsection{Creating a thread}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx}{Link to source. [MSDN]}
\begin{verbatim}
HANDLE WINAPI CreateThread(
  _In_opt_   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_       SIZE_T dwStackSize,
  _In_       LPTHREAD_START_ROUTINE lpStartAddress,
  _In_opt_   LPVOID lpParameter,
  _In_       DWORD dwCreationFlags,
  _Out_opt_  LPDWORD lpThreadId
);
\end{verbatim}

The key attributes here are {\em lpStartAddress}, {\em lpParameter}, and {\em lpThreadId}. First, {\em lpStartAddress} is the function which the thread will execute and is the starting address for the thread. Next {\em lpParameter} is the pointer to a variable that is passed to the thread. Finally, {\em lpThreadId} is the identifier of the thread. This is placed in the object pointed to by the attribute. If this is set as NULL, no identifier is passed.

\subsubsection{Return}
This function returns the thread's handle if successful, and NULL if it fails.

\subsection{Termination of a thread}

Similar to terminating a process, you must {\em wait} on the thread before closing its respective handler.

We are now introduced to the {\em WaitForMultipleObjects()} function.
\subsubsection{{\em WaitForMultipleObjects()} Description}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025%28v=vs.85%29.aspx}{Link to source. [MSDN]}
\begin{verbatim}
DWORD WINAPI WaitForMultipleObjects(
  _In_  DWORD nCount,
  _In_  const HANDLE *lpHandles,
  _In_  BOOL bWaitAll,
  _In_  DWORD dwMilliseconds
);
\end{verbatim}

This function will wait for multiple objects to complete their tasks and return. If {\em bWaitAll} is set to TRUE, then the function will wait for all functions to be in the signaled state before returning. Otherwise, it will return the first object to change its state to signaled. {\em nCount} signifies the number of objects you want to wait on (typically the size of the array of objects). {\em lpHandles} are the array of handles that need to be waited on.

\subsubsection{Return}

{\em WaitForMultipleObjects()} returns similarly to {\em WaitForSingleObject}, but returns a list of handles if {\em bWaitAll} is set to TRUE, or the first handle to change its state to signaled if set to FALSE. Both unsuccessful returns are the same.

\subsection{Example}
\begin{verbatim}
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#define MAX_THREADS 3
#define BUF_SIZE 255

DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);

// Sample custom data structure for threads to use.
// This is passed by void pointer so it can be any data type
// that can be passed using a single void pointer (LPVOID).
typedef struct MyData {
    int val1;
    int val2;
} MYDATA, *PMYDATA;


int _tmain()
{
    PMYDATA pDataArray[MAX_THREADS];
    DWORD   dwThreadIdArray[MAX_THREADS];
    HANDLE  hThreadArray[MAX_THREADS]; 

    // Create MAX_THREADS worker threads.

    for( int i=0; i<MAX_THREADS; i++ )
    {
        // Allocate memory for thread data.

        pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                sizeof(MYDATA));

        if( pDataArray[i] == NULL )
        {
           // If the array allocation fails, the system is out of memory
           // so there is no point in trying to print an error message.
           // Just terminate execution.
            ExitProcess(2);
        }

        // Generate unique data for each thread to work with.

        pDataArray[i]->val1 = i;
        pDataArray[i]->val2 = i+100;

        // Create the thread to begin execution on its own.

        hThreadArray[i] = CreateThread( 
            NULL,                   // default security attributes
            0,                      // use default stack size  
            MyThreadFunction,       // thread function name
            pDataArray[i],          // argument to thread function 
            0,                      // use default creation flags 
            &dwThreadIdArray[i]);   // returns the thread identifier 


        // Check the return value for success.
        // If CreateThread fails, terminate execution. 
        // This will automatically clean up threads and memory. 

        if (hThreadArray[i] == NULL) 
        {
           ErrorHandler(TEXT("CreateThread"));
           ExitProcess(3);
        }
    } // End of main thread creation loop.

    // Wait until all threads have terminated.

    WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);

    // Close all thread handles and free memory allocations.

    for(int i=0; i<MAX_THREADS; i++)
    {
        CloseHandle(hThreadArray[i]);
        if(pDataArray[i] != NULL)
        {
            HeapFree(GetProcessHeap(), 0, pDataArray[i]);
            pDataArray[i] = NULL;    // Ensure address is not reused.
        }
    }

    return 0;
}


DWORD WINAPI MyThreadFunction( LPVOID lpParam ) 
{ 
    HANDLE hStdout;
    PMYDATA pDataArray;

    TCHAR msgBuf[BUF_SIZE];
    size_t cchStringSize;
    DWORD dwChars;

    // Make sure there is a console to receive output results. 

    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
    if( hStdout == INVALID_HANDLE_VALUE )
        return 1;

    // Cast the parameter to the correct data type.
    // The pointer is known to be valid because 
    // it was checked for NULL before the thread was created.
 
    pDataArray = (PMYDATA)lpParam;

    // Print the parameter values using thread-safe functions.

    StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), 
        pDataArray->val1, pDataArray->val2); 
    StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
    WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);

    return 0; 
} 



void ErrorHandler(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code.

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message.

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); 

    // Free error-handling buffer allocations.

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}
\end{verbatim}
\newpage

\section{Socket Programming}

The basic structure of socket programming in Windows is very similar to that of the POSIX API. This is because the WinSock API (as it is known) is somewhat based off of the POSIX API. 
\begin{itemize}
\item Initialize socket information
\item Create socket
\item Bind socket to an address and port
\item Connect socket to server, or have the server listen for connections and accept them
\item Perform input/output
\item Close connection
\end{itemize}
What POSIX does best is treat sockets like files, allowing simple read/write system calls to be used. Fortunately, Windows allows for simple read/write calls to the socket handler as well. This makes writing POSIX- and Windows-compliant socket-based applications relatively easy. First we will start off with creating a socket.

\subsection{Creating the socket}

\subsubsection{{\em socket()} Description}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms740506%28v=vs.85%29.aspx}{Link to source. [MSDN]}
This function is formatted similarly to the POSIX version and requires the same attributes.

\begin{verbatim}
SOCKET WSAAPI socket(
  _In_  int af,
  _In_  int type,
  _In_  int protocol
);
\end{verbatim}

{\em af} is the address family you wish to specify, which can be AF\textunderscore UNSPEC (unspecified), AF\textunderscore INET (IPv4), or AF\textunderscore INET6. {\em type} is what you use to determine socket type, either SOCK\textunderscore STREAM (TCP) or SOCK\textunderscore DATA (UDP). {\em protocol} is the protocol you want to use. Typically this is either UDP or TCP.

\subsubsection{Return}

This returns a descriptor that references the new socket. If unsuccessful, the function returns a value of INVALID\textunderscore SOCKET.

\subsection{Terminating a socket}

\subsubsection{{\em closesocket()} Description}
\href{http://msdn.microsoft.com/en-us/library/windows/desktop/ms737582%28v=vs.85%29.aspx}{Link to source. [MSDN]}

\begin{verbatim}
int closesocket(
  _In_  SOCKET s
);
\end{verbatim}

This function allows you to close a socket that is not in use. {\em s} is the socket's descriptor given by the {\em socket()} function call. Much like closing a regular file, this closes all connections leading to the socket, not allowing any more I/O to be performed on it.

\subsubsection{Return}

{\em closesocket()} returns zero on success, and SOCKET\textunderscore ERROR on an unsuccessful socket close attempt.

\subsection{Example}

This is for a client.

\begin{verbatim}
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>


// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")


#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"

int __cdecl main(int argc, char **argv) 
{
    WSADATA wsaData;
    SOCKET ConnectSocket = INVALID_SOCKET;
    struct addrinfo *result = NULL,
                    *ptr = NULL,
                    hints;
    char *sendbuf = "this is a test";
    char recvbuf[DEFAULT_BUFLEN];
    int iResult;
    int recvbuflen = DEFAULT_BUFLEN;
    
    // Validate the parameters
    if (argc != 2) {
        printf("usage: %s server-name\n", argv[0]);
        return 1;
    }

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    ZeroMemory( &hints, sizeof(hints) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
    if ( iResult != 0 ) {
        printf("getaddrinfo failed with error: %d\n", iResult);
        WSACleanup();
        return 1;
    }

    // Attempt to connect to an address until one succeeds
    for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {

        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
            ptr->ai_protocol);
        if (ConnectSocket == INVALID_SOCKET) {
            printf("socket failed with error: %ld\n", WSAGetLastError());
            WSACleanup();
            return 1;
        }

        // Connect to server.
        iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
            continue;
        }
        break;
    }

    freeaddrinfo(result);

    if (ConnectSocket == INVALID_SOCKET) {
        printf("Unable to connect to server!\n");
        WSACleanup();
        return 1;
    }

    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf("send failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %ld\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf("shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf("Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            printf("Connection closed\n");
        else
            printf("recv failed with error: %d\n", WSAGetLastError());

    } while( iResult > 0 );

    // cleanup
    closesocket(ConnectSocket);
    WSACleanup();

    return 0;
}
\end{verbatim}

\end{document}
